package com.gking.processHarvest.service.Role;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gking.processHarvest.common.BaseContext;
import com.gking.processHarvest.common.Res;
import com.gking.processHarvest.entity.*;
import com.gking.processHarvest.mapper.RoleMapper;
import com.gking.processHarvest.realm.MyRealm;
import com.gking.processHarvest.service.Master.MasterService;
import com.gking.processHarvest.service.Permissions.PermissionsService;
import com.gking.processHarvest.service.RolePs.RolePsService;
import com.gking.processHarvest.service.RoleUser.RoleUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;


@Slf4j
@Service
@Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)//三级缓存解决bean循环注入问题
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {


    @Autowired
    private RoleUserService roleUserService;

    @Autowired
    private PermissionsService permissionsService;

    @Autowired
    private RolePsService rolePsService;

    @Autowired
    private MasterService masterService;

    @Autowired
    private MyRealm myRealm;



    /**
     * 获取角色列表
     *
     * @return s
     */
    @Override
    public Res<List<Role>> getRoleList() {
        List<Role> list = this.list();
        log.warn("获取角色列表详情 list : {}", list);
        return Res.success("获取成功", list);
    }


    /**
     * 获取权限列表
     *
     * @return s
     */
    @Override
    public Res<List<Permissions>> getPermissionsList() {
        List<Permissions> list = permissionsService.list();
        log.warn("获取权限列表详情 list : {}", list);
        return Res.success("获取成功", list);
    }


    /**
     * 获取角色权限详情
     *
     * @param roleId 角色id
     * @return s
     */
    @Override
    public Res<List<RolePs>> getRolePermissionsDetail(String roleId) {
        //查询角色id是否存在
        if (this.getById(roleId) == null) return Res.error("暂无该角色");

        LambdaQueryWrapper<RolePs> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RolePs::getRid, roleId);
        List<RolePs> list = rolePsService.list(wrapper);

        log.warn("查询 角色id: {} 的权限详情为： {}", roleId, list);
        return Res.success("获取角色权限详情成功", list);
    }


    /**
     * 为角色设置权限
     *
     * @param roleId          角色id
     * @param permissionsList 权限id 列表
     * @return s
     */
    @Override
    public Res<String> setRolePermissions(String roleId, List<String> permissionsList) {

        List<RolePs> rolePermissions = new ArrayList<>();
        for (String permissionsId : permissionsList) {
            //遍历传递过来的权限列表，查看数据库是否有该权限
            Permissions one = permissionsService.getById(permissionsId);
            if (one == null) return Res.error("为角色设置权限失败！");

            //存在的话，设置角色权限列表
            RolePs rolePs = new RolePs();
            rolePs.setRid(roleId);
            rolePs.setPid(permissionsId);
            rolePermissions.add(rolePs);
        }

        LambdaQueryWrapper<RolePs> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RolePs::getRid, roleId);

        //将角色原有的权限全部删除
        rolePsService.remove(queryWrapper);
        //重新给角色设置权限
        rolePsService.saveBatch(rolePermissions);
        //清除Shiro缓存
        myRealm.clearCached();

        return Res.success("角色设置权限成功！");
    }


    /**
     * 获取用户角色详情
     *
     * @return s
     */
    @Override
    public Res<List<RoleUser>> getUserRolesDetail() {
        LambdaQueryWrapper<RoleUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RoleUser::getUid, BaseContext.getCurrentId());

        List<RoleUser> list = roleUserService.list(wrapper);
        return Res.success("获取用户角色详情", list);
    }


    /**
     * 为用户设置角色
     *
     * @param roleList 角色id 列表
     * @return s
     */
    @Override
    public Res<String> setUserRoles(List<String> roleList) {

        List<RoleUser> userRoles = new ArrayList<>();
        for (String roleId : roleList) {
            //遍历传递过来的角色列表，查看数据库是否存在该角色
            Role one = this.getById(roleId);
            if (one == null) return Res.error("设置角色失败！");

            //存在的话，设置用户角色列表
            RoleUser roleUser = new RoleUser();
            roleUser.setUid(BaseContext.getCurrentId());
            roleUser.setRid(roleId);
            userRoles.add(roleUser);
        }

        LambdaQueryWrapper<RoleUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RoleUser::getUid, BaseContext.getCurrentId());

        //将用户原有的角色全部删除
        roleUserService.remove(queryWrapper);
        //重新给用户设置角色
        roleUserService.saveBatch(userRoles);
        //清除Shiro缓存
        myRealm.clearCached();

        return Res.success("设置角色成功");
    }


    /**
     * 通过userId获取用户的所有角色
     *
     * @param userId 用户id
     * @return s
     */
    @Override
    public List<String> getUserRoleListByUserId(String userId) {
        //通过账号查询出用户信息
        Master master = masterService.getById(userId);

        //通过用户信息中的用户数据查询出用户角色列表
        LambdaQueryWrapper<RoleUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RoleUser::getUid, master.getId());
        List<RoleUser> list = roleUserService.list(wrapper);

        //通过用户角色列表中的角色id查询出角色列表
        List<String> roleList = new ArrayList<>();
        for (RoleUser roleUser : list) {
            Role role = this.getById(roleUser.getRid());
            roleList.add(role.getName());
        }

        log.warn("角色列表： {} ", roleList);
        return roleList;
    }


    /**
     * 通过角色列表获取权限列表
     *
     * @param roleList 角色列表
     * @return s
     */
    @Transactional
    @Override
    public List<String> getUserPermissionsListByRoles(List<String> roleList) {
        //通过角色列表查询到角色id
        List<String> roleIdList = new ArrayList<>();
        for (String roleName : roleList) {
            LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Role::getName, roleName);
            Role role = this.getOne(queryWrapper);
            roleIdList.add(role.getId());
        }

        //通过角色id列表查询到权限id列表
        List<String> permissionsIdList = new ArrayList<>();
        for (String roleId : roleIdList) {
            LambdaQueryWrapper<RolePs> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(RolePs::getRid, roleId);
            List<RolePs> rolePsList = rolePsService.list(wrapper);

            for (RolePs rolePs : rolePsList) permissionsIdList.add(rolePs.getPid());
        }

        //对权限id列表进行去重，并通过权限id列表查询到权限列表
        List<String> pIdList = new ArrayList<>(new HashSet<>(permissionsIdList));
        List<String> permissionsInfo = new ArrayList<>();
        for (String pId : pIdList) {
            Permissions permissions = permissionsService.getById(pId);
            permissionsInfo.add(permissions.getInfo());
        }

        log.warn("权限列表： {} ", permissionsInfo);
        return permissionsInfo;
    }

}
